#!/usr/bin/env python3
#  
# 1. 定义 Spark 的基本结构信息
# 2. 定义对 Spark 的相关请求操作
# 3. 对请求的数据进行分析
#   3.1 建立对 Packages 文件的分析过程
#   3.1 建立对 Packages 文件中每个包信息的简单分析过程
# 
# 4. 利用多线程加速分析
#
# 5. 变更为标准命令行工具
#   5.1 使用 getopt 进行 python 程序参数操作
#   5.2 可解析 Spark 的离线 Packages 或 在线解析 Spark 源的包信息
#   5.3 解析 Spark 包信息提供包下载地址
# 

import getopt
import json
import sys

from spark import Spark
from spark import ResloveList, ResloveWorkPool


pool = ResloveWorkPool()

def ContentReslove(content) -> ResloveList:
    ''' 内容解析 '''
    packages = content.split("\n\n")
    pool.append([package.strip() for package in packages])
    pool.start()
    pool.wait()
    return pool.resloves

def FileReslove(filepath) -> ResloveList:
    ''' 本地文件解析 '''
    with open(filepath, 'r', errors='ignore') as f:
        content = f.read()
        return ContentReslove(content)

def checkUsage(usage):
    if len(sys.argv[1:]) == 0:
        print(usage)
        exit(0)

if __name__ == "__main__":

    # 1. 解析本地文件 Packages
    # resloves = FileReslove("Packages")
    # print("已解析:", len(resloves))

    useFile = False
    useVerbose = False
    useSearch = False
    useList = False
    useJson = False
    useJsonOut = False
    
    filePath = ""
    fileJsonOut = ""
    searchKey = ""

    usage = """Usage:
    {} [-hvlj] [-f <Packages>] [-s|--search <search package>] [--jsonout=<outfile>]
        -f        
           使用本地来源的 Packages 文件进行解析
        -s        
           搜索本地来源或在线来源中出现的关键词(例如 spark-store)
        -j        
           使用 json 格式输出搜索结果
        --jsonout=<output>
           指定写入结果的文件(使用 -j 时有效)""".format(sys.argv[0]) 
    
    checkUsage(usage)

    # C 语言风格的参数适配器
    # 例如 -f: 则表示 -f 将接收一个用户输入参数，风格与 sys.argv[1:] 一致
    # 这个程序 -f: -s: -jout: 三者均表示接收一个用户输入
    # -f 本地的 Packages 文件
    # -s 搜索的名称
    # -jout 输出到指定的文件(前提：使用 -j 表示输出结果为 json，当包含 -j 时 -jout 才会生效)
    opts,args = getopt.getopt(sys.argv[1:], "-h-v-f:-s:-l-j", ["help","verbose","file","search","list","json","jsonout="])
    for opt_name, opt_value in opts:
        if opt_name in ('-h',"--help"):
            print(usage)
            exit(0)

        if opt_name in ('-f',"--file"):
            useFile = True
            filePath = opt_value

        if opt_name in ('-v',"--verbose"):
            useVerbose = True

        if opt_name in ('-s',"--search"):
            useSearch = True
            searchKey = opt_value
        
        if opt_name in ('-l', "--list"):
            useList = True
            
        if opt_name in ('-j', "--json"):
            useJson = True
        
        if opt_name in ("--jsonout"):
            useJsonOut = True
            fileJsonOut = opt_value
    # debug:
    #     print(opt_name, opt_value)
    # print(useJson and useJsonOut, fileJsonOut)
    # -f docs/Packages
    # -s submitter
    # -j 
    # --jsonout submitter.json
    # True submitter.json
    
    resloves = ResloveList()
    # -f 读取的目标，-j 使用 json 输出，-jout 存入json数据到指定文件
    
    # 1. 使用 -f 与未使用 -f 时获取的解析来源不同
    if useFile:
        resloves = FileReslove(filePath)
    else:
        resloves = ContentReslove(Spark.getSparkPackages())

    if useSearch:
        for pkg in resloves:
            if searchKey in pkg[Spark.KEY_Package]:
                if useVerbose:
                    print(Spark.KEY_Package+":",pkg[Spark.KEY_Package])
                    for key in Spark.KEYS:
                        if key == Spark.KEY_Package: 
                            continue
                        if key in pkg.keys(): 
                            print("    -->",key+":", pkg[key])
                elif useList:
                    print(Spark.KEY_Package+":",pkg[Spark.KEY_Package], pkg[Spark.KEY_Version])
                elif useJson and useJsonOut:
                    # print(json.dumps(pkg,ensure_ascii=False,indent=True))
                    with open(fileJsonOut, 'w') as f:
                        f.write(json.dumps(pkg,ensure_ascii=False,indent=True))
                        f.flush()
                    print("write to", fileJsonOut)
                elif useJson:
                    print(json.dumps(pkg,ensure_ascii=False,indent=True))
                else:
                    print(Spark.KEY_Package+":",pkg[Spark.KEY_Package])
                    pass
        exit(0)

    if useList:
        for pkg in resloves:
            if useVerbose:
                print(Spark.KEY_Package+":",pkg[Spark.KEY_Package])
                for key in Spark.KEYS:
                    if key == Spark.KEY_Package: 
                        continue
                    if key in pkg.keys(): 
                        print("    -->",key+":", pkg[key])
            else:
                print(Spark.KEY_Package+":",pkg[Spark.KEY_Package])
        exit(0)
               

    if useJson:
        if useJsonOut:
            with open(fileJsonOut, 'w') as f:
                f.write(json.dumps(resloves,ensure_ascii=False,indent=True))
                f.flush()
        else: # 打印到标准输出
            print(json.dumps(resloves,ensure_ascii=False,indent=True))
        exit(0)